const base = require("./base");
const moment = require("moment");
const math = require("mathjs");

math.config({
    number: "BigNumber", // Default type of number:
    // 'number' (default), 'BigNumber', or 'Fraction'
    precision: 20 // Number of significant digits for BigNumbers
});

module.exports = class extends base {
    async _initialize() {
        await super.isAppAuth();
    }

    async index() {
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        let userCount = 0,
            tradeSum = 0,
            msgUnreadCount = 0;
        if (wxa) {
            const user = await this.model("user")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.count("id");
                })
                .fetch();
            userCount = user["count(`id`)"];

            const trade = await this.model("trade")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.sum("money");
                })
                .fetch();
            tradeSum = trade["sum(`money`)"];

            const wxaMsg = await this.model("wxa_msg")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("unread", 0);
                    qb.count("id");
                })
                .fetch();
            msgUnreadCount = wxaMsg["count(`id`)"];
        }
        this.success({ userCount, tradeSum, msgUnreadCount });
    }

    async dailySummaryLine() {
        const { date, field = "user" } = this.post;
        const started_at = date[0];
        const ended_at = date[1];
        const days = moment(ended_at).diff(moment(started_at), "days");
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        // 获取日期
        const dates = [];
        for (let i = days; i >= 0; i--) {
            dates.push(
                moment(ended_at)
                    .subtract(i, "days")
                    .format("YYYYMMDD")
            );
        }

        // 获取数据
        const data = [];
        if (wxa) {
            const analysis = await this.model("analysis_wxa_daily_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.whereIn("ref_date", dates);
                })
                .fetchAll();

            for (const key in dates) {
                let has = false;
                for (const k in analysis) {
                    if (dates[key] === analysis[k].ref_date) {
                        data.push(analysis[k][field]);
                        has = true;
                    }
                }

                if (!has) {
                    data.push(0);
                }
            }
        } else {
            for (const key in dates) {
                data.push(0);
            }
        }

        this.success({ dates, data });
    }

    /**
     *
     * @api {get} /app/home/analysis/user 用户分析
     * @apiDescription 用户分析
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/user
     *
     */

    async user() {
        const appId = this.state.app.id;

        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        let userCount = 0,
            visitorSum = 0,
            userNow = 0,
            user = 0;
        const date = moment().format("YYYYMMDD");
        const dates = moment(date)
            .subtract(1, "days")
            .format("YYYYMMDD");

        if (wxa) {
            userCount = await this.model("user")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.count("id");
                })
                .fetch();
            userCount = userCount["count(`id`)"];
            visitorSum = await this.model("analysis_wxa_daily_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.sum("visitor");
                })
                .fetch();
            visitorSum = visitorSum["sum(`visitor`)"];
            userNow = await this.model("analysis_wxa_daily_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("ref_date", date);
                })
                .fetch();
            user = await this.model("analysis_wxa_daily_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("ref_date", dates);
                })
                .fetch();
        }
        this.success({ userCount, visitorSum, userNow, user });
    }

    /**
     *
     * @api {post} /app/home/analysis/userChart 用户分析（折线图）
     * @apiDescription 用户分析（折线图）
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     * @apiParam {String} date 日期
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/userChart
     *
     */
    async userChart() {
        const date = this.post;
        const started_at = moment(date[0]).format("YYYY-MM-DD");
        const ended_at = moment(date[1]).format("YYYY-MM-DD");
        const days = moment(ended_at).diff(moment(started_at), "days");
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();
        // 获取日期
        const dates = [];
        for (let i = days; i >= 0; i--) {
            dates.push(
                moment(ended_at)
                    .subtract(i, "days")
                    .format("YYYYMMDD")
            );
        }

        // 获取数据
        const dataUser = [];
        const datavisitor = [];
        if (wxa) {
            const analysis = await this.model("analysis_wxa_daily_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.whereIn("ref_date", dates);
                })
                .fetchAll();

            for (const key in dates) {
                let has = false;
                for (const k in analysis) {
                    if (dates[key] === analysis[k].ref_date) {
                        dataUser.push(analysis[k]["user"]);
                        datavisitor.push(analysis[k]["visitor"]);
                        has = true;
                    }
                }

                if (!has) {
                    dataUser.push(0);
                    datavisitor.push(0);
                }
            }
        } else {
            for (const key in dates) {
                dataUser.push(0);
                datavisitor.push(0);
            }
        }

        this.success({ dates, dataUser, datavisitor });
    }

    /**
     *
     * @api {post} /app/home/analysis/tradeList 交易列表
     * @apiDescription 交易列表
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     * @apiParam {String} tradeid      交易单号
     * @apiParam {String} started_at   开始日期
     * @apiParam {String} ended_at     结束日期
     * @apiParam {Number} status       状态(1:支付 0：未支付)
     * @apiParam {Number} page         页码
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/tradeList
     *
     */

    async tradeList() {
        const {
            tradeid = "",
            started_at = "",
            ended_at = "",
            status = "",
            page = 1
        } = this.post;
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        // 获取数据
        let trade = {
            data: [],
            pagination: {
                page: 1,
                pageSize: 20,
                rowCount: 0,
                pageCount: 1
            }
        };

        if (wxa) {
            trade = await this.model("trade")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    if (this.isSet(status)) {
                        qb.where("status", status);
                    }
                    if (this.isSet(tradeid)) {
                        qb.where("tradeid", "like", `${tradeid}`);
                    }
                    if (!this.isSet(started_at) && this.isSet(ended_at)) {
                        qb.where("created_at", "<=", `${ended_at}`);
                    }
                    if (this.isSet(started_at) && !this.isSet(ended_at)) {
                        qb.where("created_at", ">=", `${started_at}`);
                    }
                    if (this.isSet(started_at) && this.isSet(ended_at)) {
                        qb.where("created_at", ">=", `${started_at}`);
                        qb.where("created_at", "<=", `${ended_at}`);
                    }
                    qb.orderBy("id", "desc");
                })
                .fetchPage({ page: page, pageSize: 20, withRelated: ["user"] });
        }

        this.success(trade);
    }
    /**
     *
     * @api {get} /app/home/analysis/trade 交易分析
     * @apiDescription 交易分析
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/trade
     *
     */

    async trade() {
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        let tradeCount = 0,
            tradeSum = 0,
            dateNowCount = 0,
            dateNowSum = 0,
            dateCount = 0,
            dateSum = 0;
        const date = moment(moment().format("YYYY-MM-DD")).format(
            "YYYY-MM-DD HH:mm:ss"
        );
        const dates = moment(date)
            .subtract(1, "days")
            .format("YYYY-MM-DD HH:mm:ss");
        const dated = moment(date)
            .add(1, "days")
            .format("YYYY-MM-DD HH:mm:ss");
        if (wxa) {
            const trade = await this.model("trade")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                })
                .fetchAll();
            for (const k in trade) {
                if (trade[k].status === 1) {
                    tradeCount = math.format(
                        math.eval(`${tradeCount} + ${trade[k].money}`)
                    );
                }
                if (trade[k].status === 0) {
                    tradeSum = math.format(
                        math.eval(`${tradeSum} + ${trade[k].money}`)
                    );
                }
                if (
                    date <=
                        moment(trade[k].created_at).format(
                            "YYYY-MM-DD HH:mm:ss"
                        ) &&
                    dated >=
                        moment(trade[k].created_at).format(
                            "YYYY-MM-DD HH:mm:ss"
                        )
                ) {
                    if (trade[k].status === 1) {
                        dateNowCount = math.format(
                            math.eval(`${dateNowCount} + ${trade[k].money}`)
                        );
                    }
                    if (trade[k].status === 0) {
                        dateNowSum = math.format(
                            math.eval(`${dateNowSum} + ${trade[k].money}`)
                        );
                    }
                }
                if (
                    date >=
                        moment(trade[k].created_at).format(
                            "YYYY-MM-DD HH:mm:ss"
                        ) &&
                    dates <=
                        moment(trade[k].created_at).format(
                            "YYYY-MM-DD HH:mm:ss"
                        )
                ) {
                    if (trade[k].status === 1) {
                        dateCount = math.format(
                            math.eval(`${dateCount} + ${trade[k].money}`)
                        );
                    }
                    if (trade[k].status === 0) {
                        dateSum = math.format(
                            math.eval(`${dateSum} + ${trade[k].money}`)
                        );
                    }
                }
            }
        }
        this.success({
            tradeCount,
            tradeSum,
            dateNowCount,
            dateNowSum,
            dateCount,
            dateSum
        });
    }

    /**
     *
     * @api {post} /app/home/analysis/tradeChart 交易分析（折线图）
     * @apiDescription 交易分析（折线图）
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     * @apiParam {String} date 日期
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/tradeChart
     *
     */

    async tradeChart() {
        const date = this.post;
        const started_at = date[0];
        const ended_at = date[1];
        const days = moment(ended_at).diff(moment(started_at), "days");
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        // 获取日期
        const dates = [];
        for (let i = days; i >= 0; i--) {
            dates.push(
                moment(ended_at)
                    .subtract(i, "days")
                    .format("YYYYMMDD")
            );
        }

        // 获取数据
        const dataCount = [];
        const dataSum = [];
        if (wxa) {
            const dateNowSum = await this.model("trade")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("created_at", ">=", started_at);
                    qb.where("created_at", "<=", ended_at);
                })
                .fetchAll();
            for (const key in dates) {
                const data = moment(dates[key]).format("YYYY-MM-DD HH:mm:ss");
                const datas = moment(dates[key])
                    .add(1, "days")
                    .format("YYYY-MM-DD HH:mm:ss");
                let payMoney = 0;
                let money = 0;
                for (const k in dateNowSum) {
                    if (
                        data <=
                            moment(dateNowSum[k].created_at).format(
                                "YYYY-MM-DD HH:mm:ss"
                            ) &&
                        datas >=
                            moment(dateNowSum[k].created_at).format(
                                "YYYY-MM-DD HH:mm:ss"
                            )
                    ) {
                        if (dateNowSum[k].status === 1) {
                            payMoney = math.format(
                                math.eval(
                                    `${payMoney} + ${dateNowSum[k].money}`
                                )
                            );
                        } else {
                            money = math.format(
                                math.eval(`${money} + ${dateNowSum[k].money}`)
                            );
                        }
                    }
                }

                dataCount.push(payMoney);
                dataSum.push(money);
            }
        } else {
            for (const key in dates) {
                dataCount.push(0);
                dataSum.push(0);
            }
        }

        this.success({ dates, dataCount, dataSum });
    }

    /**
     *
     * @api {get} /app/home/analysis/productList 商品分析列表
     * @apiDescription 商品分析列表
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     * @apiParam {String} date   日期
     * @apiParam {Number} page   页码
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/productList
     *
     */

    async productList() {
        const { date = "", page = 1 } = this.query;
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();

        // 获取数据
        let product = {
            data: [],
            pagination: {
                page: 1,
                pageSize: 20,
                rowCount: 0,
                pageCount: 1
            }
        };

        if (wxa) {
            product = await this.model("analysis_product_effect_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    if (this.isSet(date)) {
                        qb.where("ref_date", moment(date).format("YYYYMMDD"));
                    }
                    qb.orderBy("id", "desc");
                })
                .fetchPage({
                    page: page,
                    pageSize: 20,
                    withRelated: ["product"]
                });
        }

        this.success(product);
    }
    /**
     *
     * @api {get} /app/home/analysis/product 商品分析
     * @apiDescription 商品分析
     * @apiGroup App Home
     * @apiVersion 0.0.1
     *
     * @apiHeader {String} Token 用户登录授权token.
     *
     * @apiParam {String} date   日期
     *
     * @apiSuccess {Array} success 应用列表
     *
     * @apiSampleRequest /app/home/analysis/product
     *
     */

    async product() {
        const { date = "" } = this.query;
        const appId = this.state.app.id;
        const wxa = await this.model("wxa")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();
        const shop = await this.model("shop")
            .query(qb => {
                qb.where("app_id", appId);
            })
            .fetch();
        let productCount = 0,
            productSum = 0,
            percent = 0;
        const dates = date
            ? moment(moment(date).format("YYYY-MM-DD")).format(
                  "YYYY-MM-DD HH:mm:ss"
              )
            : moment(moment().format("YYYY-MM-DD")).format(
                  "YYYY-MM-DD HH:mm:ss"
              );
        const dated = moment(date)
            .add(1, "days")
            .format("YYYY-MM-DD HH:mm:ss");
        if (shop) {
            productCount = await this.model("product")
                .query(qb => {
                    qb.where("shop_id", shop.id);
                    qb.where("status", 1);
                    // if (this.isSet(date)) {
                    //     qb.where("created_at", ">=", dates);
                    //     qb.where("created_at", "<", dated);
                    // }
                    qb.count("id");
                })
                .fetch();
            productCount = productCount["count(`id`)"];
        }
        if (wxa) {
            productSum = await this.model("analysis_product_summary")
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    if (!this.isSet(date)) {
                        qb.where("ref_date", moment().format("YYYYMMDD"));
                    }
                    if (this.isSet(date)) {
                        qb.where("ref_date", moment(dates).format("YYYYMMDD"));
                    }
                })
                .fetch();
            const productVisitor = await this.model(
                "analysis_product_effect_summary"
            )
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("ref_date", moment(dates).format("YYYYMMDD"));
                    qb.sum("visitor");
                })
                .fetch();
            const productTrade = await this.model(
                "analysis_product_effect_summary"
            )
                .query(qb => {
                    qb.where("wxa_id", wxa.id);
                    qb.where("ref_date", moment(dates).format("YYYYMMDD"));
                    qb.sum("trade");
                })
                .fetch();
            if (
                productVisitor["sum(`visitor`)"] &&
                productTrade["sum(`trade`)"]
            ) {
                percent = math.format(
                    math.eval(
                        `100 *${productTrade["sum(`trade`)"]} / ${
                            productVisitor["sum(`visitor`)"]
                        }`
                    )
                );
                percent = Number(percent).toFixed(2);
            }
        }
        this.success({
            productCount,
            productSum,
            percent
        });
    }
};
